package edu.cs.usask.ca.silver.api.businesslogic;

import java.util.Date;

import edu.cs.usask.ca.silver.api.persistence.StorageI;
import edu.cs.usask.ca.silver.businesslogic.ids.FileID;
import edu.cs.usask.ca.silver.businesslogic.ids.ModelProjectID;
import edu.cs.usask.ca.silver.businesslogic.ids.ModelVersionID;
import edu.cs.usask.ca.silver.businesslogic.ids.ScenarioCollectionID;
import edu.cs.usask.ca.silver.businesslogic.ids.ScenarioID;

/**
 * 
 * Specification of all necessary functionality of ModelVersion Beans (local and
 * remote).
 * 
 * @author Daniel Funk
 * 
 */
public interface ModelVersionI {

	/**
	 * Creates an empty ModelVersion within a specified project.
	 * 
	 * @param vName
	 *            The version name
	 * @param vCreator
	 *            Version creator
	 * @param vDescr
	 *            Version description
	 * @param mpId
	 *            The parent project Id
	 * @param storage TODO
	 * @return A unique ModelVersion ID
	 * @throws Exception
	 */
	public ModelVersionID createGenericModelVersion(String vName, String vCreator,
			String vDescr, ModelProjectID mpId, StorageI storage) throws Exception;

	/**
	 * Create a ModelVersion from source file
	 * 
	 * @param name
	 * @param creator
	 * @param descr
	 * @param mpId
	 * @param sourceFileLocation
	 * @param visibility
	 * @param storage TODO
	 * @param classFileLocation
	 * @return
	 * @throws Exception
	 */
	public ModelVersionID createGenericModelVersionFromLocalInputFile(String name,
			String creator, String descr, ModelProjectID mpId,
			String sourceFileLocation, int visibility, StorageI storage) throws Exception;

	/**
	 * Set Source file to ModelVersion and Create ORIGINAL Scenario Collection
	 * and Scenario. to anylogic support
	 * 
	 * @param mvId
	 * @param sourceFileLocation
	 * @param jarFileLoc
	 *            TODO
	 * @return true if succeed, false if failed.
	 * 
	 * @throws Exception
	 */
	// public boolean addSourceToModelVersion(ModelVersionID mvId,
	// String sourceFileLocation, String classFileLocation)
	// throws Exception;

	/**
	 * Add source file to Model Version
	 * 
	 * @param mvId
	 * @param sourceFileLocation
	 * @param storage TODO
	 */
	public void addSourceToModelVersion(ModelVersionID mvId,
			String sourceFileLocation, StorageI storage) throws Exception;

	/**
	 * Add source file and input file to Model Version
	 * 
	 * @param mvId
	 *            unique modelversion id
	 * @param sourceFileLocation
	 *            Anylogic alp file location
	 * @param classFileLocation
	 *            Anylogic generated class file location
	 * @param storage TODO
	 */
	public boolean interpretAnylogicSourceFileAndPackClassFilesToModelVersion(ModelVersionID mvId,
			String sourceFileLocation, String classFileLocation, StorageI storage)
			throws Exception;

	/**
	 * Returns a string containing the XML representation of this version
	 * (non-recursive)
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return String of XML representation
	 * @throws Exception
	 */
	public String getModelVersionAsXML(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the name of the version
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return String containing the version name
	 * @throws Exception
	 */
	public String getName(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the type of the version
	 * 
	 * @param mvId
	 * @param storage TODO
	 * @return String containing the type of this version "VENSIM" - vensim
	 *         "ANYLOGIC" - anylogic, "UNSPECIFED" for any Unspecified type
	 * @throws Exception
	 */
	public String getType(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the description of a version as string
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return The version description
	 * @throws Exception
	 */
	public String getDescription(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the version creator as String
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return The version creator
	 * @throws Exception
	 */
	public String getCreator(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the creation date of this version
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return The version creation date
	 * @throws Exception
	 */
	public Date getCreationDate(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the creation time of this version
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return The version creation date with specific time
	 * @throws Exception
	 */
	public Date getCreationTime(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns an array of FileIDs of all files associated with this model
	 * version
	 * 
	 * @param mvId
	 *            A unique ModelVersionID
	 * @param storage TODO
	 * @return Array of fileIDs of all file associated with this version
	 * @throws Exception
	 */
	public FileID[] getAssociatedFileIds(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the ModelProjectID of the parent project
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return The unique ModelProject ID of the parent project
	 * @throws Exception
	 */
	public ModelProjectID getParentProjectId(ModelVersionID mvId, StorageI storage)
			throws Exception;

	/**
	 * Returns the unique FileID of the source file from which this version was
	 * created
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return A unique FileID
	 * @throws Exception
	 */
	public FileID getSourceFileId(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the name of the source file from which this version is created
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return The name of the ModelVersion source file
	 * @throws NullPointerException
	 *             - if the ModelVersion does not have a source file
	 */
	public String getSourceFileName(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Returns the unique ScenarioID of the original Scenario for this version
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return A unique ScenarioID for the original scenario
	 * @throws Exception
	 */
	public ScenarioID getOriginalScenarioId(ModelVersionID mvId, StorageI storage)
			throws Exception;

	/**
	 * Returns the unique ScenarioID of the baseline Scenario for this version
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return A unique ScenarioID for the baseline scenario
	 * @throws Exception
	 */
	public ScenarioID getBaselineScenarioId(ModelVersionID mvId, StorageI storage)
			throws Exception;

	/**
	 * Takes the original sourcefile for this model version and saves it to a
	 * specified location on disk
	 * @param destLoc
	 *            The location at which the file should be saved
	 * @param storage TODO
	 * @param mvID
	 *            A unique ModelVersion ID
	 * 
	 * @throws Exception
	 */
	public void recreateOriginalSourceFileToDisk(ModelVersionID mvId,
			String destLoc, StorageI storage) throws Exception;

	/**
	 * Export all input files from the ORIGINAL SCENARIO of this model version
	 * and saves it to a specified location on disk.
	 * 
	 * input files includes the (in most cases just) jarfile needed to run the
	 * simulation.
	 * @param destLoc
	 *            The file path INCLUDING the file name to be saved. (USE FILE
	 *            SEPERATOR TO APPEND THE FILE NAME AND EXTENSION TO THE PATH)
	 * @param storage TODO
	 * @param mvID
	 *            A unique ModelVersion ID
	 * 
	 * @throws Exception
	 */
	public void recreateOriginalInputFilesToDisk(ModelVersionID mvId,
			String destLoc, StorageI storage) throws Exception;

	/**
	 * Returns the ScenarioID of the most recently created Scenario
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @return The unique ScenarioID of the most recently created Scenario
	 * @throws Exception
	 */
	// public ScenarioID getMostRecentScenarioId(ModelVersionID mvId)
	// throws Exception;

	/**
	 * Returns and array of unique ScenarioCollectionIDs, the collections
	 * contained within this version
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param storage TODO
	 * @return An array of ScenarioCollectionIDs
	 * @throws Exception
	 */
	public ScenarioCollectionID[] getScenarioCollectionIds(ModelVersionID mvId, StorageI storage)
			throws Exception;

	/**
	 * Returns the id of the most recently created scenario collection
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @return The unique scenarioCollectionID of the most recently created
	 *         scenario collection
	 * @throws Exception
	 */
	// public ScenarioCollectionID getMostRecentScenarioCollectionId(
	// ModelVersionID mvId) throws Exception;

	/**
	 * Set the name of a model version in the storage layer
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param name
	 *            The (new) name of a model version
	 * @param storage TODO
	 * @return TODO
	 * @throws Exception
	 */
	public boolean setName(ModelVersionID mvId, String name, StorageI storage) throws Exception;

	/**
	 * Change/Set the type of a model version in the storage layer
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param type
	 *            The type of a model version
	 * @param storage TODO
	 * @return TODO
	 * @throws Exception
	 */
	public boolean setType(ModelVersionID mvId, String type, StorageI storage) throws Exception;

	/**
	 * Set the description of a model version in the storage layer
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param description
	 *            The (new) version description
	 * @param storage TODO
	 * @throws Exception
	 */
	public boolean setDescription(ModelVersionID mvId, String description, StorageI storage)
			throws Exception;

	/**
	 * Change the baseline scenario for this version
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param sId
	 *            A unique Scenario ID, the (new) baseline scenario
	 * @param storage TODO
	 * @return TODO
	 * @throws Exception
	 */
	public boolean setBaselineScenario(ModelVersionID mvId, ScenarioID sId, StorageI storage)
			throws Exception;

	/**
	 * Change the original scenario for this version
	 * 
	 * @param mvId
	 *            A unique ModelVersion ID
	 * @param sId
	 *            A unique Scenario ID, the (new) original scenario
	 * @param storage TODO
	 * @return TODO
	 * @throws Exception
	 */
	public boolean setOriginalScenario(ModelVersionID mvId, ScenarioID sId, StorageI storage)
			throws Exception;

	/**
	 * Removes a model version from storage (including all collections,
	 * scenarios, etc.)
	 * 
	 * @param mvId
	 * @param storage TODO
	 * @return TODO
	 * @throws Exception
	 */
	public boolean deleteVersion(ModelVersionID mvId, StorageI storage) throws Exception;

	/**
	 * Duplicate a scenario collection from another scenario collection
	 * 
	 * @param scId
	 *            A unique ScenarioCollectionID
	 * @param mvId
	 *            A unique ModelVersionID of the destination model version
	 * @param storage TODO
	 * @return A unique ScenarioCollectionID of the duplicated scenario
	 *         collection
	 */
	public ScenarioCollectionID duplicateScenarioCollection(
			ScenarioCollectionID scId, ModelVersionID mvId, StorageI storage) throws Exception;

	public ModelVersionID createVensimModelVersion(String vName, String vCreator,
			String vDescr, ModelProjectID mpId, StorageI storage)
			throws Exception;

	public ModelVersionID createVensimModelVersionFromLocalInputFile(String vName,
			String vCreator, String vDescr, ModelProjectID mpId,
			String sourceFileLocation, int visibility, StorageI storage)
			throws Exception, UnsatisfiedLinkError;

	public ModelVersionID createAnylogicModelVersionFromLocalInputFile(String vName,
			String vCreator, String vDescr, ModelProjectID mpId,
			String sourceFileLocation, String classFiles, int visibility,
			StorageI storage) throws Exception;

	public ModelVersionID createAnylogicModelVersion(String vName, String vCreator,
			String vDescr, ModelProjectID mpId, StorageI storage)
			throws Exception;
}
